home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1997 December / MACPOWER-1997-12.ISO.7z / MACPOWER-1997-12.ISO / AMUG / PROGRAMMING / Raven 1.2.sit / Raven 1.2 / Source / Foundation / OS / ZRegion.cpp < prev    next >
Text File  |  1997-02-01  |  11KB  |  634 lines

  1. /*
  2.  *  File:       ZRegion.h
  3.  *  Summary:       RgnHandle wrapper.
  4.  *  Written by: Jesse Jones
  5.  *
  6.  *  Copyright ゥ 1996 Jesse Jones. 
  7.  *    For conditions of distribution and use, see copyright notice in ZTypes.h  
  8.  *
  9.  *  Change History (most recent first):    
  10.  *
  11.  *         <->     1/28/96    JDJ        Created
  12.  */
  13.  
  14. #include <ZRegion.h>
  15.  
  16. #include <ZDebug.h>
  17. #include <ZExceptions.h>
  18. #include <ZQueue.h>
  19.  
  20.  
  21. // ===================================================================================
  22. //    class ZRegionPool
  23. // ===================================================================================
  24. class ZRegionPool {
  25.  
  26. protected:
  27.                         ~ZRegionPool();
  28.                         
  29.                         ZRegionPool();
  30.  
  31. public:
  32.     static    ZRegionPool* Instance();
  33.     
  34.             RgnHandle     AcquireRegion();
  35.             
  36.             void         ReleaseRegion(RgnHandle rgn);
  37.             
  38. protected:
  39.     TQueue<RgnHandle>    mRegions;
  40. };
  41.  
  42.  
  43. //---------------------------------------------------------------
  44. //
  45. // ZRegionPool::~ZRegionPool
  46. //
  47. //---------------------------------------------------------------
  48. ZRegionPool::~ZRegionPool()
  49. {
  50.     while (!mRegions.empty()) {
  51.         RgnHandle rgn = mRegions.back();
  52.         mRegions.pop_back();
  53.         
  54.         DisposeRgn(rgn);
  55.     }
  56. }
  57.  
  58.  
  59. //---------------------------------------------------------------
  60. //
  61. // ZRegionPool::ZRegionPool
  62. //
  63. //---------------------------------------------------------------
  64. ZRegionPool::ZRegionPool()
  65. {
  66. }
  67.  
  68.  
  69. //---------------------------------------------------------------
  70. //
  71. // ZRegionPool::Instance                                [static]
  72. //
  73. //---------------------------------------------------------------
  74. ZRegionPool* ZRegionPool::Instance()
  75. {
  76.     static ZRegionPool pool;
  77.     
  78.     return &pool;
  79. }
  80.  
  81.  
  82. //---------------------------------------------------------------
  83. //
  84. // ZRegionPool::AcquireRegion
  85. //
  86. //---------------------------------------------------------------
  87. RgnHandle ZRegionPool::AcquireRegion()
  88. {
  89.     RgnHandle rgn = nil;
  90.     
  91.     if (!mRegions.empty()) {
  92.         rgn = mRegions.back();
  93.         mRegions.pop_back();
  94.     
  95.     } else {
  96.         rgn = NewRgn();
  97.         ThrowIfNil(rgn);
  98.     }
  99.     
  100.     return rgn;
  101. }
  102.  
  103.  
  104. //---------------------------------------------------------------
  105. //
  106. // ZRegionPool::ReleaseRegion
  107. //
  108. //---------------------------------------------------------------
  109. void ZRegionPool::ReleaseRegion(RgnHandle rgn)
  110. {
  111.     ASSERT(rgn != nil);
  112.     
  113.     SetEmptyRgn(rgn);
  114.     
  115.     mRegions.push_back(rgn);
  116. }
  117.  
  118. #pragma mark -
  119.  
  120. // ===================================================================================
  121. //    class TRegion
  122. // ===================================================================================
  123.  
  124. //---------------------------------------------------------------
  125. //
  126. // Destructor
  127. //
  128. //---------------------------------------------------------------
  129. TRegion::~TRegion()
  130. {
  131.     if (mRgn != nil)
  132.         ZRegionPool::Instance()->ReleaseRegion(mRgn);
  133. }
  134.     
  135.     
  136. //---------------------------------------------------------------
  137. //
  138. // Constructors
  139. //
  140. //---------------------------------------------------------------
  141. TRegion::TRegion()
  142. {
  143.     mRgn = ZRegionPool::Instance()->AcquireRegion();
  144. }
  145.  
  146. TRegion::TRegion(const TRegion& rgn)
  147. {
  148.     mRgn = ZRegionPool::Instance()->AcquireRegion();
  149.     
  150.     CopyRgn(rgn, mRgn);
  151.     ThrowIfQDError();
  152. }
  153.  
  154. TRegion::TRegion(RgnHandle rgn)
  155. {
  156.     ASSERT(rgn != nil);
  157.     
  158.     mRgn = ZRegionPool::Instance()->AcquireRegion();
  159.  
  160.     CopyRgn(rgn, mRgn);
  161.     ThrowIfQDError();
  162. }
  163.  
  164. TRegion::TRegion(const TRect& rect)
  165. {
  166.     mRgn = ZRegionPool::Instance()->AcquireRegion();
  167.  
  168.     RectRgn(mRgn, rect);
  169.     ThrowIfQDError();
  170. }
  171.  
  172. TRegion::TRegion(const TPoint& pt, const TSize& size)
  173. {
  174.     mRgn = ZRegionPool::Instance()->AcquireRegion();
  175.  
  176.     RectRgn(mRgn, TRect(pt, size));
  177.     ThrowIfQDError();
  178. }
  179.  
  180. TRegion::TRegion(const TPoint* vertices, short count)
  181. {
  182.     ASSERT(vertices != nil);
  183.     ASSERT(count > 0);
  184.     
  185.     mRgn = ZRegionPool::Instance()->AcquireRegion();
  186.  
  187.     OpenRgn();
  188.     ::MoveTo(vertices[0].h, vertices[0].v);
  189.     for (short index = 1; index < count; index++) {
  190.         LineTo(vertices[index].h, vertices[index].v);
  191.     }
  192.     LineTo(vertices[0].h, vertices[0].v);
  193.     CloseRgn(mRgn);
  194.  
  195.     ThrowIfQDError();
  196. }
  197.  
  198.  
  199. //---------------------------------------------------------------
  200. //
  201. // Assignment
  202. //
  203. //---------------------------------------------------------------
  204. TRegion& TRegion::operator=(const TRegion& rgn)
  205. {
  206.     if (this != &rgn && *this != rgn) {
  207.         RgnHandle temp = ZRegionPool::Instance()->AcquireRegion();
  208.  
  209.         CopyRgn(rgn, temp);
  210.         ThrowIfQDError();
  211.  
  212.         ZRegionPool::Instance()->ReleaseRegion(mRgn);
  213.         mRgn = temp;
  214.     }
  215.     
  216.     return *this;
  217. }
  218.  
  219. TRegion& TRegion::operator=(const TRect& rect)
  220. {
  221.     if (*this != rect) {
  222.         RgnHandle temp = ZRegionPool::Instance()->AcquireRegion();
  223.  
  224.         RectRgn(temp, rect);
  225.         ThrowIfQDError();
  226.  
  227.         ZRegionPool::Instance()->ReleaseRegion(mRgn);
  228.         mRgn = temp;
  229.     }
  230.     
  231.     return *this;
  232. }
  233.  
  234.  
  235. TRegion& TRegion::operator+=(const TRegion& rgn)
  236. {
  237.     RgnHandle temp = ZRegionPool::Instance()->AcquireRegion();
  238.  
  239.     UnionRgn(mRgn, rgn, temp);
  240.     ThrowIfQDError();
  241.  
  242.     ZRegionPool::Instance()->ReleaseRegion(mRgn);
  243.     mRgn = temp;
  244.  
  245.     return *this;
  246. }
  247.  
  248. TRegion& TRegion::operator+=(const TRect& rect)
  249. {
  250.     RgnHandle temp = ZRegionPool::Instance()->AcquireRegion();
  251.  
  252.     RectRgn(temp, rect);
  253.     ThrowIfQDError();
  254.  
  255.     UnionRgn(mRgn, temp, temp);
  256.     ThrowIfQDError();
  257.  
  258.     ZRegionPool::Instance()->ReleaseRegion(mRgn);
  259.     mRgn = temp;
  260.     
  261.     return *this;
  262. }
  263.  
  264. TRegion& TRegion::operator+=(const TPoint& offset)
  265. {
  266.     TRect src, dst;
  267.     
  268.     src = dst = (**mRgn).rgnBBox;
  269.     dst += offset;
  270.     
  271.     ::MapRgn(mRgn, src, dst);
  272.  
  273.     return *this;
  274. }
  275.  
  276. TRegion& TRegion::operator-=(const TRegion& rgn)
  277. {
  278.     RgnHandle temp = ZRegionPool::Instance()->AcquireRegion();
  279.  
  280.     DiffRgn(mRgn, rgn, temp);
  281.     ThrowIfQDError();
  282.  
  283.     ZRegionPool::Instance()->ReleaseRegion(mRgn);
  284.     mRgn = temp;
  285.  
  286.     return *this;
  287. }
  288.  
  289. TRegion& TRegion::operator-=(const TRect& rect)
  290. {
  291.     RgnHandle temp = ZRegionPool::Instance()->AcquireRegion();
  292.  
  293.     RectRgn(temp, rect);
  294.     ThrowIfQDError();
  295.  
  296.     DiffRgn(mRgn, temp, temp);
  297.     ThrowIfQDError();
  298.  
  299.     ZRegionPool::Instance()->ReleaseRegion(mRgn);
  300.     mRgn = temp;
  301.     
  302.     return *this;
  303. }
  304.  
  305. TRegion& TRegion::operator-=(const TPoint& offset)
  306. {
  307.     TRect src, dst;
  308.     
  309.     src = dst = (**mRgn).rgnBBox;
  310.     dst -= offset;
  311.     
  312.     ::MapRgn(mRgn, src, dst);
  313.  
  314.     return *this;
  315. }
  316.  
  317. TRegion& TRegion::operator&=(const TRegion& rgn)
  318. {
  319.     RgnHandle temp = ZRegionPool::Instance()->AcquireRegion();
  320.  
  321.     SectRgn(mRgn, rgn, temp);
  322.     ThrowIfQDError();
  323.  
  324.     ZRegionPool::Instance()->ReleaseRegion(mRgn);
  325.     mRgn = temp;
  326.  
  327.     return *this;
  328. }
  329.  
  330. TRegion& TRegion::operator&=(const TRect& rect)
  331. {
  332.     RgnHandle temp = ZRegionPool::Instance()->AcquireRegion();
  333.  
  334.     RectRgn(temp, rect);
  335.     ThrowIfQDError();
  336.  
  337.     SectRgn(mRgn, temp, temp);
  338.     ThrowIfQDError();
  339.  
  340.     ZRegionPool::Instance()->ReleaseRegion(mRgn);
  341.     mRgn = temp;
  342.     
  343.     return *this;
  344. }
  345.  
  346. TRegion& TRegion::operator^=(const TRegion& rgn)
  347. {
  348.     RgnHandle temp = ZRegionPool::Instance()->AcquireRegion();
  349.  
  350.     XorRgn(mRgn, rgn, temp);
  351.     ThrowIfQDError();
  352.  
  353.     ZRegionPool::Instance()->ReleaseRegion(mRgn);
  354.     mRgn = temp;
  355.  
  356.     return *this;
  357. }
  358.  
  359. TRegion& TRegion::operator^=(const TRect& rect)
  360. {
  361.     RgnHandle temp = ZRegionPool::Instance()->AcquireRegion();
  362.  
  363.     RectRgn(temp, rect);
  364.     ThrowIfQDError();
  365.  
  366.     XorRgn(mRgn, temp, temp);
  367.     ThrowIfQDError();
  368.  
  369.     ZRegionPool::Instance()->ReleaseRegion(mRgn);
  370.     mRgn = temp;
  371.     
  372.     return *this;
  373. }
  374.  
  375.  
  376. //---------------------------------------------------------------
  377. //
  378. // Arithmetic
  379. //
  380. //---------------------------------------------------------------
  381. TRegion operator+(const TRegion& rgn1, const TRegion& rgn2)
  382. {
  383.     TRegion newRgn;
  384.     
  385.     UnionRgn(rgn1, rgn2, newRgn);
  386.     ThrowIfQDError();
  387.  
  388.     return newRgn;
  389. }
  390.  
  391. TRegion operator+(const TRegion& rgn, const TRect& rect)
  392. {
  393.     TRegion newRgn(rect);
  394.     
  395.     UnionRgn(rgn, newRgn, newRgn);
  396.     ThrowIfQDError();
  397.  
  398.     return newRgn;
  399. }
  400.  
  401. TRegion operator+(const TRect& rect, const TRegion& rgn)
  402. {
  403.     TRegion newRgn(rect);
  404.     
  405.     UnionRgn(newRgn, rgn, newRgn);
  406.     ThrowIfQDError();
  407.  
  408.     return newRgn;
  409. }
  410.  
  411.  
  412. TRegion operator-(const TRegion& rgn1, const TRegion& rgn2)
  413. {
  414.     TRegion newRgn;
  415.     
  416.     DiffRgn(rgn1, rgn2, newRgn);
  417.     ThrowIfQDError();
  418.  
  419.     return newRgn;
  420. }
  421.  
  422. TRegion operator-(const TRegion& rgn, const TRect& rect)
  423. {
  424.     TRegion newRgn(rect);
  425.     
  426.     DiffRgn(rgn, newRgn, newRgn);
  427.     ThrowIfQDError();
  428.  
  429.     return newRgn;
  430. }
  431.  
  432. TRegion operator-(const TRect& rect, const TRegion& rgn)
  433. {
  434.     TRegion newRgn(rect);
  435.  
  436.     DiffRgn(newRgn, rgn, newRgn);
  437.     ThrowIfQDError();
  438.  
  439.     return newRgn;
  440. }
  441.  
  442.  
  443. TRegion operator&(const TRegion& rgn1, const TRegion& rgn2)
  444. {
  445.     TRegion newRgn;
  446.     
  447.     SectRgn(rgn1, rgn2, newRgn);
  448.     ThrowIfQDError();
  449.  
  450.     return newRgn;
  451. }
  452.  
  453. TRegion operator&(const TRegion& rgn, const TRect& rect)
  454. {
  455.     TRegion newRgn(rect);
  456.     
  457.     SectRgn(rgn, newRgn, newRgn);
  458.     ThrowIfQDError();
  459.  
  460.     return newRgn;
  461. }
  462.  
  463. TRegion operator&(const TRect& rect, const TRegion& rgn)
  464. {
  465.     TRegion newRgn(rect);
  466.     
  467.     SectRgn(newRgn, rgn, newRgn);
  468.     ThrowIfQDError();
  469.  
  470.     return newRgn;
  471. }
  472.  
  473.  
  474. TRegion operator^(const TRegion& rgn1, const TRegion& rgn2)
  475. {
  476.     TRegion newRgn;
  477.     
  478.     XorRgn(rgn1, rgn2, newRgn);
  479.     ThrowIfQDError();
  480.  
  481.     return newRgn;
  482. }
  483.  
  484. TRegion operator^(const TRegion& rgn, const TRect& rect)
  485. {
  486.     TRegion newRgn(rect);
  487.     
  488.     XorRgn(rgn, newRgn, newRgn);
  489.     return newRgn;
  490. }
  491.  
  492. TRegion operator^(const TRect& rect, const TRegion& rgn)
  493. {
  494.     TRegion newRgn(rect);
  495.     
  496.     XorRgn(newRgn, rgn, newRgn);
  497.     ThrowIfQDError();
  498.  
  499.     return newRgn;
  500. }
  501.  
  502.  
  503. void TRegion::MakeEmpty()
  504. {
  505.     SetEmptyRgn(mRgn);
  506. }
  507.  
  508.  
  509. void TRegion::Map(const TRect& srcRect, const TRect& dstRect)    
  510. {
  511.     RgnHandle temp = ZRegionPool::Instance()->AcquireRegion();
  512.  
  513.     CopyRgn(mRgn, temp);
  514.     ThrowIfQDError();
  515.  
  516.     ::MapRgn(temp, srcRect, dstRect);
  517.     ThrowIfQDError();
  518.  
  519.     ZRegionPool::Instance()->ReleaseRegion(mRgn);
  520.     mRgn = temp;
  521. }
  522.  
  523.  
  524. //---------------------------------------------------------------
  525. //
  526. // Comparison
  527. //
  528. //---------------------------------------------------------------
  529. bool operator==(const TRegion& rgn1, const TRegion& rgn2)
  530. {
  531.     return EqualRgn(rgn1, rgn2);
  532. }
  533.  
  534. bool operator==(const TRegion& rgn, const TRect& rect)
  535. {
  536.     RgnHandle temp = ZRegionPool::Instance()->AcquireRegion();
  537.  
  538.     RectRgn(temp, rect);
  539.     ThrowIfQDError();
  540.  
  541.     bool equal = EqualRgn(rgn, temp);
  542.     ZRegionPool::Instance()->ReleaseRegion(temp);
  543.     
  544.     return equal;
  545. }
  546.  
  547. bool operator==(const TRect& rect, const TRegion& rgn)
  548. {
  549.     RgnHandle temp = ZRegionPool::Instance()->AcquireRegion();
  550.  
  551.     RectRgn(temp, rect);
  552.     ThrowIfQDError();
  553.  
  554.     bool equal = EqualRgn(rgn, temp);
  555.     ZRegionPool::Instance()->ReleaseRegion(temp);
  556.     
  557.     return equal;
  558. }
  559.  
  560.  
  561. bool operator!=(const TRegion& rgn1, const TRegion& rgn2)
  562. {
  563.     return !EqualRgn(rgn1, rgn2);
  564. }
  565.  
  566. bool operator!=(const TRegion& rgn, const TRect& rect)
  567. {
  568.     RgnHandle temp = ZRegionPool::Instance()->AcquireRegion();
  569.  
  570.     RectRgn(temp, rect);
  571.     ThrowIfQDError();
  572.  
  573.     bool equal = EqualRgn(rgn, temp);
  574.     ZRegionPool::Instance()->ReleaseRegion(temp);
  575.     
  576.     return !equal;
  577. }
  578.  
  579. bool operator!=(const TRect& rect, const TRegion& rgn)
  580. {
  581.     RgnHandle temp = ZRegionPool::Instance()->AcquireRegion();
  582.  
  583.     RectRgn(temp, rect);
  584.     ThrowIfQDError();
  585.  
  586.     bool equal = EqualRgn(rgn, temp);
  587.     ZRegionPool::Instance()->ReleaseRegion(temp);
  588.     
  589.     return !equal;
  590. }
  591.  
  592.  
  593. //---------------------------------------------------------------
  594. //
  595. // Moving
  596. //
  597. //---------------------------------------------------------------
  598. TRegion operator+(const TRegion& rgn, const TPoint& offset)
  599. {
  600.     TRegion result = rgn;
  601.  
  602.     TRect src, dst;
  603.     
  604.     src = dst = (**result).rgnBBox;
  605.     dst += offset;
  606.     
  607.     ::MapRgn(result, src, dst);
  608.  
  609.     return result;
  610. }
  611.  
  612. TRegion operator-(const TRegion& rgn, const TPoint& offset)
  613. {
  614.     TRegion result = rgn;
  615.  
  616.     TRect src, dst;
  617.     
  618.     src = dst = (**result).rgnBBox;
  619.     dst -= offset;
  620.     
  621.     ::MapRgn(result, src, dst);
  622.  
  623.     return result;
  624. }
  625.  
  626.  
  627. void TRegion::MoveTo(const TPoint& pt)
  628. {
  629.     TPoint offset(pt - ((TRect) (**mRgn).rgnBBox)[topLeft]);
  630.     
  631.     ::OffsetRgn(mRgn, offset.h, offset.v);
  632. }
  633.  
  634.